package com.example.children.config;


import com.example.children.Util.JwtUtil;
import com.example.children.annotation.AllowGuestAccess;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

public class JwtTest implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("JwtFilter-init");
         Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        System.out.println("JwtFilter-doFilter");
        // 使用 jakarta.servlet.http.HttpServletRequest 和 jakarta.servlet.http.HttpServletResponse
        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;

        String uri = httpRequest.getRequestURI();

        // 判断请求的 URI 是否是登录或注册相关的接口
            if (uri.contains("/login") || uri.contains("/register") || uri.contains("/guestLogin") || uri.contains("/refreshToken")) {
            System.out.println("可放行端口：如登录,注册等等");
            // 登录和注册接口不需要鉴权，直接放行
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            System.out.println("游客？");
            handleGuestAccess( servletRequest, servletResponse,filterChain);
            System.out.println("不是游客，需要验证双Token！！！");
            String authorizationHeader = httpRequest.getHeader("Authorization");

            // 检查 Authorization header 是否存在且以 "Bearer " 开头
            if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
                System.out.println("携带请求头！！！");
                String token = authorizationHeader.substring(7);  // 提取 Bearer 后的 Token
                // 验证 token
                if (JwtUtil.validateToken(token)) {
                    // 如果验证通过，继续执行请求链
                    System.out.println("验证通过，放行，继续执行请求链");
                    filterChain.doFilter(servletRequest, servletResponse);
                } else {
                    System.out.println("主令牌都过期了，你还来干什么");
                    // 如果 token 验证失败，设置状态码为 401 Unauthorized，并返回错误信息
                    sendUnauthorizedResponse(httpResponse, "令牌无效");
                }
            } else {
                System.out.println("不携带请求头？？？？？所以你干什么来了？？？");
                // 如果缺少 Authorization header，返回 401 Unauthorized
                sendUnauthorizedResponse(httpResponse, "缺少 Authorization 标头");
            }
        }
    }



    // 这是过滤器的主要方法，用来处理游客请求
    public void handleGuestAccess(ServletRequest servletRequest, ServletResponse servletResponse,
                                  FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
        String role = httpRequest.getParameter("role");  // 获取请求参数中的role
        if (role != null && role.equals("guest")) {
            System.out.println("游客");
            String uri = httpRequest.getRequestURI();  // 获取请求的URI
            String[] pathParts = uri.split("/");  // 按 "/" 分割 URI
            // 获取 URI 中的第一个部分作为类名
            String className = pathParts.length > 1 ? pathParts[1] : null;
            if (className != null) {
                try {
                    // 拼接完整的类名，假设类名是 "user" 对应的 Java 类是 "User.class"
                    String fullClassName = "com.example.children.controller." + capitalizeFirstLetter(className);
                    System.out.println("Full class name: " + fullClassName); // 打印拼接后的类名，检查是否正确
                    // 动态加载类
                    Class<?> clazz = Class.forName(fullClassName);
                    // 从 URI 中提取方法名
                    String methodName = uri.substring(uri.lastIndexOf("/") + 1);
                    // 获取类中的所有方法
                    Method[] declaredMethods = clazz.getDeclaredMethods();
                    System.out.println("游客访问的方法:");
                    // 遍历方法，检查是否有符合游客访问的注解
                    for (Method method : declaredMethods) {
                        System.out.println("游客进入到 " + method.getName() + " 方法");
                        // 检查方法上是否有 AllowGuestAccess 注解，并且方法名匹配
                        if (method.getAnnotation(AllowGuestAccess.class) != null && method.getName().equals(methodName)) {
                            filterChain.doFilter(httpRequest, httpResponse);  // 如果符合条件，继续执行过滤链
                            return;  // 找到匹配方法后直接返回
                        }
                    }
                    // 如果没有找到匹配的访问方法，返回未授权错误
                    System.err.println("未找到url中游客的对应方法！！");
                    errorUnauthorizedResponse(httpResponse, "未找到url中游客的对应方法！！");
                } catch (ClassNotFoundException e) {
                    System.err.println("游客访问方法错误！！！");
                    e.printStackTrace();  // 处理类未找到的异常
                    roleUnauthorizedResponse(httpResponse, "无法找到类：" + e.getMessage());
                }
            } else {
                errorUnauthorizedResponse(httpResponse, "无效的 URI，缺少类名！");
            }
        }
    }

    // 辅助方法：将类名的首字母大写
    private String capitalizeFirstLetter(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }


    //错误返回 401
    private void sendUnauthorizedResponse(HttpServletResponse response, String message) throws IOException {
        // 设置状态码为 401 Unauthorized
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        // 设置响应内容类型为 JSON（你也可以根据需要使用纯文本）
        response.setContentType("application/json");
        // 输出详细的错误信息
        String jsonResponse = "{\"error\": \"Unauthorized\", \"message\": \"" + message + "\"}";
        response.getWriter().write(jsonResponse);
    }


    //错误返回 403 权限错误
    private void roleUnauthorizedResponse(HttpServletResponse response, String message) throws IOException {
        // 设置状态码为 403 Unauthorized
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        // 设置响应内容类型为 JSON（你也可以根据需要使用纯文本）
        response.setContentType("application/json");
        // 输出详细的错误信息
        String jsonResponse = "{\"error\": \"Unauthorized\", \"message\": \"" + message + "\"}";
        response.getWriter().write(jsonResponse);
    }


    //错误返回 500 错误
    private void errorUnauthorizedResponse(HttpServletResponse response, String message) throws IOException {
        // 设置状态码为 500 Unauthorized
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        // 设置响应内容类型为 JSON（你也可以根据需要使用纯文本）
        response.setContentType("application/json");
        // 输出详细的错误信息
        String jsonResponse = "{\"error\": \"Unauthorized\", \"message\": \"" + message + "\"}";
        response.getWriter().write(jsonResponse);
    }



}

